package com.imdroid.carac.activities;

import java.nio.ByteBuffer;
import java.util.Timer;
import java.util.TimerTask;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationManager;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.Vibrator;
import android.text.Html;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.BDNotifyListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.map.Geometry;
import com.baidu.mapapi.map.Graphic;
import com.baidu.mapapi.map.GraphicsOverlay;
import com.baidu.mapapi.map.ItemizedOverlay;
import com.baidu.mapapi.map.LocationData;
import com.baidu.mapapi.map.MKMapViewListener;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationOverlay;
import com.baidu.mapapi.map.OverlayItem;
import com.baidu.mapapi.map.RouteOverlay;
import com.baidu.mapapi.map.Symbol;
import com.baidu.mapapi.map.TextItem;
import com.baidu.mapapi.map.TextOverlay;
import com.baidu.mapapi.navi.BaiduMapAppNotSupportNaviException;
import com.baidu.mapapi.navi.BaiduMapNavigation;
import com.baidu.mapapi.navi.NaviPara;
import com.baidu.mapapi.search.MKAddrInfo;
import com.baidu.mapapi.search.MKBusLineResult;
import com.baidu.mapapi.search.MKDrivingRouteResult;
import com.baidu.mapapi.search.MKPlanNode;
import com.baidu.mapapi.search.MKPoiResult;
import com.baidu.mapapi.search.MKSearch;
import com.baidu.mapapi.search.MKSearchListener;
import com.baidu.mapapi.search.MKSuggestionResult;
import com.baidu.mapapi.search.MKTransitRouteResult;
import com.baidu.mapapi.search.MKWalkingRouteResult;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import com.baidu.platform.comapi.map.Projection;
import com.imdroid.carac.IMDroid;
import com.imdroid.carac.R;
import com.imdroid.carac.audioCodec.StreamListener;
import com.imdroid.carac.audioCodec.UDPMicrophone;
import com.imdroid.carac.audioCodec.UDPSpeaker;
import com.imdroid.carac.model.Team;
import com.imdroid.carac.model.TeamMember;
import com.imdroid.carac.process.PlaySoundProcess;
import com.imdroid.carac.process.ProcessFactory;
import com.imdroid.carac.process.TeamProcess;
import com.imdroid.carac.services.UDPServer;

public class TeamMapActivity extends Activity {
	/**
	 * The tag of the map activity
	 */
	private static final String TAG = "TeamMapActivity";
	/**
	 * The map view;
	 */
	private MapView mapView;
	/**
	 * The image of the speaker when the team call is recording.
	 */
	private View callView;
	/**
	 * The map manager
	 */
	private BMapManager bMapManager;
	/**
	 * The controller of the map;
	 */
	private MapController mapController;
	/**
	 * The MK Search
	 */
	private MKSearch mKSearch;
	/**
	 * The team leader overy lay
	 */
	private MyLocationOverlay teamLeaderOverlay = null;
	/**
	 * The team leader overy lay
	 */
	private TeamMemberOverlay teamMemberOverlay = null;
	/**
	 * The team leader overy lay
	 */
	private DestinationOverlay destinationOverlay = null;
	/**
	 * The route overlay
	 */
	private RouteOverlay routeOverlay = null;
	/**
	 * The line between team member
	 */
	private GraphicsOverlay lineOverlay = null;
	private TextOverlay txtOverlay = null;
	// 定位相关
	private LocationClient mLocClient;
	private MyLocationListenner myListener = new MyLocationListenner();
	private LocationData locData = null;
	/**
	 * The default zoon level
	 */
	private static final int defailtZoomLevel = 15;
	/**
	 * if current status is in navigation - it will lock my position
	 */
	private boolean isNavigation = true;
	/**
	 * The current location
	 */
	private static BDLocation currentLocation;
	/**
	 * The current location
	 */
	private static String currentCity;
	/**
	 * The active instance
	 */
	public static TeamMapActivity instance = null;
	/**
	 * The message handler
	 */
	private Handler messageHandler;

	/**
	 * The wake lock to control the screen
	 */
	PowerManager.WakeLock wakeLock;

	/**
	 * The audio manager
	 */
	private AudioManager audioManager;

	/**
	 * The gesture detector
	 */
	private GestureDetector gestureDetector;
	/**
	 * The events
	 */

	// exit the map and team
	public static final int EVENT_TEAM_EXIT = 0x1001;
	// refresh all the team member
	public static final int EVENT_TEAM_REFRESH = 0x1002;
	// Update all the team member position
	public static final int EVENT_TEAM_UPDATE = 0x1003;
	// Sent location to other members
	public static final int EVENT_TEAM_SEND_LOCATION = 0x1004;
	// Sent location to other members
	public static final int EVENT_TEAM_SEND_DEST_NO_ROUTE = 0x1005;
	// Sent location to other members
	public static final int EVENT_TEAM_SEND_DEST_WITH_ROUTE = 0x1006;
	// Show or Hide the members
	public static final int EVENT_TEAM_SHOW_MEMBERS = 0x1007;
	// Show or Hide the members
	public static final int EVENT_TEAM_HIDE_MEMBERS = 0x1009;
	// Receive the destination
	public static final int EVENT_TEAM_RECEIVE_LOCATION = 0x1008;
	// change the call animation
	public static final int EVENT_CHANGE_CALL_ANIM_ICON = 0x2001;
	/**
	 * If it is active
	 */
	private boolean active;
	private boolean bupdateMe = true;
	/**
	 * If the map in mute mode
	 */
	// private volatile boolean mute = false;
	// private static final int DISMISS_DIALOG = 1;
	private volatile boolean backgroundRunning = false;
//	private btctrl btService;
	private static final int BTCTL_KEY_UP_STATUS = 0;
	private static final int BTCTL_KEY_ENTER_STATUS = 1;
	private static final int BTCTL_KEY_DOWN_STATUS = 2;

	// the animation icons.
	private static final int[] anim_icons_left = { R.drawable.recordingr0,
			R.drawable.recordingr1, R.drawable.recordingr2,
			R.drawable.recordingr3 };
	private static final int[] anim_icons_right = { R.drawable.recording0,
			R.drawable.recording1, R.drawable.recording2, R.drawable.recording3 };
	// the animation timer.
	private Timer animTimer;
	private TimerTask animTask;

	// arrow for members direction
	private int intDirection = 8;
	private int[] arrayHeading = new int[] { 22, 67, 112, 157, 202, 247, 292,
			337 };
	private final int arrow_Member[] = new int[intDirection + 1];
	private final int arrow_Member_Lite[] = new int[intDirection + 1];
	private final int arrow_Leader[] = new int[intDirection + 1];
	private final int arrow_Leader_Lite[] = new int[intDirection + 1];
	private final int arrow_Me[] = new int[intDirection + 1];
	private final int arrow_Me_Member[] = new int[intDirection + 1];

	private int arrowHeight;
	public static int lastHeading = 0;

	public void onCreate(Bundle savedInstanceState) {
		// 初始化界面
		super.onCreate(savedInstanceState);
		setContentView(R.layout.team_map_main);

		// 设置各个按钮控件
		mapView = (MapView) this.findViewById(R.id.team_map_main);

		Button callButton = ((Button) this.findViewById(R.id.team_map_call));
		callButton.setOnTouchListener(callOnTouchListener);
		ScrollView scrollView = (ScrollView) findViewById(R.id.team_map_member_sv);
		scrollView.setVisibility(View.GONE);
		callView = this.findViewById(R.id.team_map_image_record);

		// 初始化hander
		instance = this;
		setActive(true);
		initHandler();

		// 初始化后台按键服务
//		 btService = new btctrl();

		// 启动通知服务，连接服务器
		// startService(new Intent(this, NotificationService.class));
		try {
			UDPServer.startup();
			UDPSpeaker.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 初始化地图
		IMDroid app = (IMDroid) this.getApplication();
		bMapManager = app.mBMapMan;
		if (bMapManager != null) {
			bMapManager.start();
		}
		// GPS定位
		mLocClient = new LocationClient(this);
		mLocClient.registerLocationListener(myListener);

		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);// 打开gps
		option.setCoorType("bd09ll"); // 设置坐标类型
		option.setScanSpan(3000);
		mLocClient.setLocOption(option);
		mLocClient.start();
		// 初始化MKSearch类:
		mKSearch = new MKSearch();
		mKSearch.init(bMapManager, mapSearchListener);
		// 设置地图中心
		isNavigation = true;
		mapController = mapView.getController();
		mapController.setZoom(defailtZoomLevel);
		mapController.enableClick(true);
		mapView.setDoubleClickZooming(true);
		mapView.setBuiltInZoomControls(false);
		mapView.setLongClickable(true);
		// 设置手势的处理
		gestureDetector = new GestureDetector(this, new MapGestureListener());
		mapView.setOnTouchListener(new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				gestureDetector.onTouchEvent(event);
				return false;
			}
		});
		mapView.regMapViewListener(app.mBMapMan, mapViewListener);
		mapView.setFocusable(true);
		mapView.setOnKeyListener(new OnKeyListener() {
			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				// SoundProcessCommons.onKeyDown(keyCode, event);
				// SoundProcessCommons.onKeyUp(keyCode, event);
				// return true;
				// 是否有键按下
//				Toast.makeText(TeamMapActivity.this, "UP", Toast.LENGTH_SHORT)
//						.show();
				if (event.getAction() == KeyEvent.ACTION_DOWN) {
					switch (keyCode) {
					case KeyEvent.KEYCODE_DPAD_UP:
						Toast.makeText(TeamMapActivity.this, "UP",
								Toast.LENGTH_SHORT).show();
						return true;
					case KeyEvent.KEYCODE_DPAD_DOWN:
						Toast.makeText(TeamMapActivity.this, "DOWN",
								Toast.LENGTH_SHORT).show();
						System.out.println("DPAD_DOWN");
						return true;
					case KeyEvent.KEYCODE_DPAD_LEFT:
						Toast.makeText(TeamMapActivity.this, "LEFT",
								Toast.LENGTH_SHORT).show();
						return true;
					case KeyEvent.KEYCODE_DPAD_RIGHT:
						Toast.makeText(TeamMapActivity.this, "RIGHT",
								Toast.LENGTH_SHORT).show();
						return true;
					default:
						return true;
					}
				} else {
					return false;
				}
			}

		});
		mapView.setFocusable(true);

		// 设置图层
		teamLeaderOverlay = new MyLocationOverlay(mapView);
		locData = new LocationData();
		teamLeaderOverlay.setData(locData);
		teamLeaderOverlay.enableCompass();
		teamMemberOverlay = new TeamMemberOverlay(this.getResources()
				.getDrawable(R.drawable.map_car_friend), mapView);
		destinationOverlay = new DestinationOverlay(getResources().getDrawable(
				R.drawable.icon_marka), mapView);
		lineOverlay = new GraphicsOverlay(mapView);
		txtOverlay = new TextOverlay(mapView);

		mapView.getOverlays().add(teamMemberOverlay);
		mapView.getOverlays().add(teamLeaderOverlay);
		mapView.getOverlays().add(lineOverlay);
		mapView.getOverlays().add(destinationOverlay);
		// mapView.getOverlays().add(txtOverlay);
		mapView.refresh();
		// 检查音量是否足够
		checkAudio();
		// 检查GPS是否打开
		checkGPS();
		// 初始化箭头
		initArrow();
		// 初始化动画定时器
		animTimer = new Timer();
		// 获取声音管理器
		audioManager = (AudioManager) this
				.getSystemService(Context.AUDIO_SERVICE);
		mapView.onResume();

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onStart()
	 */
	protected void onStart() {
		super.onStart();
		backgroundRunning = false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onResume()
	 */
	@SuppressWarnings("deprecation")
	protected void onResume() {
		super.onResume();
		// 设置不锁屏，得到wake log
		PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
		wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, this
				.getClass().getCanonicalName());
		wakeLock.acquire();

		setActive(true);

		// 如有目的地且要查找路线的
		Team team = Team.getCurrentTeam();
		// Log.d(TAG, "team...." + team);
		// if (team.isSearchRoute())
		// messageHandler.sendEmptyMessage(EVENT_TEAM_REFRESH);

		// 如果是队长，则显示下发目的地的按钮
		ImageButton button = (ImageButton) this
				.findViewById(R.id.team_map_dest);

		if (team.getTeamId() == IMDroid.getUser().getUser_id())
			button.setVisibility(View.VISIBLE);
		else
			button.setVisibility(View.GONE);

		// 刷新成员列表
		messageHandler.sendEmptyMessage(EVENT_TEAM_REFRESH);

		ScrollView scrollView = (ScrollView) findViewById(R.id.team_map_member_sv_float);
		TextView textView = (TextView) findViewById(R.id.team_map_member_tv_float);
		if (Team.getCurrentTeam().getTeamName() != ""
				&& !Team.getCurrentTeam().getTeamName().equals("")) {
			textView.setText(Team.getCurrentTeam().getTeamName());
		}
		scrollView.setVisibility(View.VISIBLE);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onPause()
	 */
	protected void onPause() {
		if (wakeLock != null)
			wakeLock.release();
		super.onPause();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onStop()
	 */
	protected void onStop() {
		super.onStop();

		backgroundRunning = true;
//		new Thread() {
//			private boolean downKeyDown = false;
//			private boolean upKeyDown = false;
//
//			public void run() {
//				while (backgroundRunning) {
//					try {
//						Thread.sleep(50);
//					} catch (Exception e) {
//					}
//					try {
//						int status = btService
//								.getKeyStatus(BTCTL_KEY_ENTER_STATUS);
//						if (status == 0) {
//							// enter pressed
//							messageHandler.post(new Runnable() {
//								public void run() {
//									onKeyDown(KeyEvent.KEYCODE_ENTER, null);
//								}
//							});
//							continue;
//						} else {
//							if (TeamCallHelper.isRecording
//									&& !TeamCallHelper.isStopping) {
//								messageHandler.post(new Runnable() {
//									public void run() {
//										onKeyUp(KeyEvent.KEYCODE_ENTER, null);
//									}
//								});
//								continue;
//							}
//						}
//						status = btService.getKeyStatus(BTCTL_KEY_DOWN_STATUS);
//						// System.out.println("down status -> " + status);
//						if (status == 0) {
//							downKeyDown = true;
//							continue;
//						} else {
//							if (downKeyDown) {
//								downKeyDown = false;
//								messageHandler.post(new Runnable() {
//									public void run() {
//										onKeyUp(KeyEvent.KEYCODE_DPAD_DOWN,
//												null);
//									}
//								});
//								continue;
//							}
//						}
//						status = btService.getKeyStatus(BTCTL_KEY_UP_STATUS);
//						// System.out.println("up status -> " + status);
//						if (status == 0) {
//							upKeyDown = true;
//							continue;
//						} else {
//							if (upKeyDown) {
//								upKeyDown = false;
//								messageHandler.post(new Runnable() {
//									public void run() {
//										onKeyUp(KeyEvent.KEYCODE_DPAD_UP, null);
//									}
//								});
//								continue;
//							}
//						}
//					} catch (Exception e) {
//						e.printStackTrace();
//					}
//				}
//			}
//		}.start();

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onDestroy()
	 */
	protected void onDestroy() {
		backgroundRunning = false;

		if (mLocClient != null) {
			mLocClient.unRegisterLocationListener(myListener);
			mLocClient.stop();
		}
		setActive(false);

		if (animTimer != null) {
			animTimer.cancel();
			animTimer = null;
		}

		if (animTask != null) {
			animTask.cancel();
			animTask = null;
		}

		if (bMapManager != null) {
			bMapManager.stop();
		}
		// mapView.onPause();

		// 关闭通知服务，与服务器断开连接
		// this.stopService(new Intent(this, NotificationService.class));
		try {
			UDPServer.shutdown();
			UDPSpeaker.stop();
			UDPMicrophone.stopRecording();
		} catch (Exception e) {
			e.printStackTrace();
		}

		mapView.getOverlays().remove(teamLeaderOverlay);
		mapView.getOverlays().remove(teamMemberOverlay);
		mapView.getOverlays().remove(destinationOverlay);
		mapView.getOverlays().remove(lineOverlay);
		super.onDestroy();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onPrepareOptionsMenu(android.view.Menu)
	 */
	public boolean onPrepareOptionsMenu(Menu menu) {
		menu.clear();
		Team team = Team.getCurrentTeam();
		int count = 0;
		SubMenu sbmTemp;
		if (team != null) {
			if (!(team.getDestinationLat() == 0 && team.getDestinationLon() == 0)) {
				sbmTemp = menu.addSubMenu(Menu.NONE, 0, Menu.NONE,
						this.getString(R.string.team_map_dest));
				count++;
			}

			for (TeamMember member : team.getMembers().values()) {
				// team leader
				sbmTemp = menu.addSubMenu(Menu.NONE, member.getId(), Menu.NONE,
						member.getDisplayName());
				// team leader
				if (member.getId() == team.getTeamId()) {
					if (member.getId() == IMDroid.getUser().getUser_id()) {
						sbmTemp.setIcon(R.drawable.arrow_me_n);
					} else {
						// client & team leader
						if (member.getDeviceType().equals("1")) {
							sbmTemp.setIcon(R.drawable.arrow_leader_n);
						} else {// lite & team leader
							sbmTemp.setIcon(R.drawable.arrow_leader_lite_n);
						}
					}
				} else {// team member
					if (member.getId() == IMDroid.getUser().getUser_id()) {
						sbmTemp.setIcon(R.drawable.arrow_me_member_n);
					} else {
						if (member.getDeviceType().equals("1")) {
							sbmTemp.setIcon(R.drawable.arrow_member_n);
						} else {
							sbmTemp.setIcon(R.drawable.arrow_member_lite_n);
						}
					}
				}
			}
		}

		// int leaderId = -1;
		// // 加入队长的位置
		// if (team.getTeamLeader() != null
		// && team.getTeamId() != team.getTeamLeader().getId()) {
		// leaderId = team.getTeamLeader().getId();
		// sbmTemp = menu.addSubMenu(Menu.NONE, team.getTeamLeader().getId(),
		// Menu.NONE, team.getTeamLeader().getDisplayName());
		// sbmTemp.setIcon(R.drawable.arrow_leader_n);
		// }
		// // 加入各个Member的位置
		// for (TeamMember member : team.getMembers().values())
		// // if (member.getId() != IMDroid.getUser().getUser_id()
		// // && member.getId() != leaderId) {
		// if (member.getId() != leaderId) {
		// sbmTemp = menu.addSubMenu(Menu.NONE, member.getId(), Menu.NONE,
		// member.getDisplayName());
		// // sbmTemp.setIcon(R.drawable.arr)
		// count++;
		// }

		// menu.add(Menu.NONE, -3, count++, "回桌面");
		// if (IMDroid.getUser().getUser_id() ==
		// Team.getCurrentTeam().getTeamId())
		// menu.add(Menu.NONE, -2, count++, "解散");

		return super.onPrepareOptionsMenu(menu);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		// 如果是导航状态，则先解锁
		if (isNavigation)
			locateMe(this.findViewById(R.id.team_map_location));
		int member_id = item.getItemId();
		Log.d(TAG, "search " + member_id);
		Team team = Team.getCurrentTeam();
		// 如果是定位目的度
		if (member_id == 0) {
			if (!(team.getDestinationLat() == 0 && team.getDestinationLon() == 0))
				mapController.setCenter(new GeoPoint((int) (team
						.getDestinationLat() * 1E6), (int) (team
						.getDestinationLon() * 1E6)));

		}

		// 如果是定位队员们
		if (member_id > 0) {
			TeamMember member = team.getMembers().get(member_id);
			if (member != null) {
				if (member.getLat() == 0 && member.getLat() == 0) {
					// 如果没有定位，
					String mess = this.getString(R.string.team_no_positon);
					mess = mess.replace("%1", member.getDisplayName());
//					Toast.makeText(this, mess, Toast.LENGTH_SHORT).show();
				} else {
					// 移动地图中心至该队员位置
					mapController.setCenter(new GeoPoint(
							(int) (member.getLat() * 1E6), (int) (member
									.getLon() * 1E6)));
				}
			}
		} else if (member_id == -1) { // 显示队员列表菜单
			startActivity(new Intent(this, MemberListActivity.class));
		} else if (member_id == -2) { // 解散队伍菜单
			// showDialog(DISMISS_DIALOG);
		} else if (member_id == -3) { // 回桌面
			Intent in = new Intent(Intent.ACTION_MAIN, null);
			in.addCategory(Intent.CATEGORY_HOME);
			startActivity(in);
		}

		return super.onOptionsItemSelected(item);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onKeyUp(int, android.view.KeyEvent)
	 */
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		// 上一条对讲
		if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
			PlaySoundProcess.seekAndPlayPrevious();
			return true;
		}// 下一条对讲
		else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {

			PlaySoundProcess.seekAndPlayNext();
			return true;
		}// // 中间对讲键
		else if (keyCode == KeyEvent.KEYCODE_ENTER) {

			callView.setVisibility(View.GONE);
			// 结束录音
			if (TeamCallHelper.isRecording && !TeamCallHelper.isStopping)
				TeamCallHelper.stopRecording();
			return true;
		}
		return super.onKeyUp(keyCode, event);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onKeyDown(int, android.view.KeyEvent)
	 */
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// Log.d(TAG,"keydown---" + keyCode);
		// 退出前确认
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			AlertDialog.Builder buidler = new AlertDialog.Builder(this);
			buidler.setMessage(R.string.team_exit_confirm);

			buidler.setPositiveButton("Ok", new OnClickListener() {
				public void onClick(DialogInterface arg0, int arg1) {
					messageHandler.sendEmptyMessage(EVENT_TEAM_EXIT);
					TeamMapActivity.this.finish();
				}
			});
			buidler.setNegativeButton("Cancel", new OnClickListener() {
				public void onClick(DialogInterface arg0, int arg1) {
					arg0.dismiss();
				}
			});

			buidler.show();
			return true;
		}
		// 上一条对讲
		if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
			// 留给onKeyUp处理
			return true;
		}
		// 下一条对讲
		if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
			// 留给onKeyUp处理
			return true;
		}
		if (keyCode == KeyEvent.KEYCODE_ENTER) {
			callView.setVisibility(View.VISIBLE);
			// 中间确认键
			if (!TeamCallHelper.isRecording && !TeamCallHelper.isStopping)
				TeamCallHelper.startRecording();

			return true;
		}

		return super.onKeyDown(keyCode, event);
	}

	/*
	 * initiate arrow for member's direction
	 */
	private void initArrow() {
		// team member
		arrow_Member[0] = (R.drawable.arrow_member_n);
		arrow_Member[1] = (R.drawable.arrow_member_0);
		arrow_Member[2] = (R.drawable.arrow_member_45);
		arrow_Member[3] = (R.drawable.arrow_member_90);
		arrow_Member[4] = (R.drawable.arrow_member_135);
		arrow_Member[5] = (R.drawable.arrow_member_180);
		arrow_Member[6] = (R.drawable.arrow_member_225);
		arrow_Member[7] = (R.drawable.arrow_member_270);
		arrow_Member[8] = (R.drawable.arrow_member_315);

		// team member for lite
		arrow_Member_Lite[0] = (R.drawable.arrow_member_lite_n);
		arrow_Member_Lite[1] = (R.drawable.arrow_member_lite_0);
		arrow_Member_Lite[2] = (R.drawable.arrow_member_lite_45);
		arrow_Member_Lite[3] = (R.drawable.arrow_member_lite_90);
		arrow_Member_Lite[4] = (R.drawable.arrow_member_lite_135);
		arrow_Member_Lite[5] = (R.drawable.arrow_member_lite_180);
		arrow_Member_Lite[6] = (R.drawable.arrow_member_lite_225);
		arrow_Member_Lite[7] = (R.drawable.arrow_member_lite_270);
		arrow_Member_Lite[8] = (R.drawable.arrow_member_lite_315);
		// team leader
		arrow_Leader[0] = (R.drawable.arrow_leader_n);
		arrow_Leader[1] = (R.drawable.arrow_leader_0);
		arrow_Leader[2] = (R.drawable.arrow_leader_45);
		arrow_Leader[3] = (R.drawable.arrow_leader_90);
		arrow_Leader[4] = (R.drawable.arrow_leader_135);
		arrow_Leader[5] = (R.drawable.arrow_leader_180);
		arrow_Leader[6] = (R.drawable.arrow_leader_225);
		arrow_Leader[7] = (R.drawable.arrow_leader_270);
		arrow_Leader[8] = (R.drawable.arrow_leader_315);

		// team leader lite
		arrow_Leader_Lite[0] = (R.drawable.arrow_leader_lite_n);
		arrow_Leader_Lite[1] = (R.drawable.arrow_leader_lite_0);
		arrow_Leader_Lite[2] = (R.drawable.arrow_leader_lite_45);
		arrow_Leader_Lite[3] = (R.drawable.arrow_leader_lite_90);
		arrow_Leader_Lite[4] = (R.drawable.arrow_leader_lite_135);
		arrow_Leader_Lite[5] = (R.drawable.arrow_leader_lite_180);
		arrow_Leader_Lite[6] = (R.drawable.arrow_leader_lite_225);
		arrow_Leader_Lite[7] = (R.drawable.arrow_leader_lite_270);
		arrow_Leader_Lite[8] = (R.drawable.arrow_leader_lite_315);

		// the arrow of me
		arrow_Me[0] = R.drawable.arrow_me_n;
		arrow_Me[1] = R.drawable.arrow_me_0;
		arrow_Me[2] = R.drawable.arrow_me_45;
		arrow_Me[3] = R.drawable.arrow_me_90;
		arrow_Me[4] = R.drawable.arrow_me_135;
		arrow_Me[5] = R.drawable.arrow_me_180;
		arrow_Me[6] = R.drawable.arrow_me_225;
		arrow_Me[7] = R.drawable.arrow_me_270;
		arrow_Me[8] = R.drawable.arrow_me_315;

		// the arrow of me as member
		arrow_Me_Member[0] = R.drawable.arrow_me_member_n;
		arrow_Me_Member[1] = R.drawable.arrow_me_member_0;
		arrow_Me_Member[2] = R.drawable.arrow_me_member_45;
		arrow_Me_Member[3] = R.drawable.arrow_me_member_90;
		arrow_Me_Member[4] = R.drawable.arrow_me_member_135;
		arrow_Me_Member[5] = R.drawable.arrow_me_member_180;
		arrow_Me_Member[6] = R.drawable.arrow_me_member_225;
		arrow_Me_Member[7] = R.drawable.arrow_me_member_270;
		arrow_Me_Member[8] = R.drawable.arrow_me_member_315;

		// arrowWidth =
		// getResources().getDrawable(R.drawable.arrow_leader_lite_0)
		// .getIntrinsicWidth();
		arrowHeight = getResources()
				.getDrawable(R.drawable.arrow_leader_lite_0)
				.getIntrinsicHeight();
	}

	private int getHeadingIndex(float targetNum) {
		// int newhdg = 0;

		if (targetNum <= 0) {
			return 0;
		} else {
			int intIndex = 0;

			int size = arrayHeading.length - 1;

			if (targetNum > arrayHeading[size]) {
				return size;
			}
			for (int i = 0; i < size; i++) {
				if (targetNum >= arrayHeading[i]
						&& targetNum < arrayHeading[i + 1]) {
					if (Math.abs(arrayHeading[i] - targetNum) > Math
							.abs(arrayHeading[i + 1] - targetNum)) {
						intIndex = i + 1;
					} else {
						intIndex = i;
					}
					break;
				}
			}
			return (intDirection - intIndex);
		}
		// int newhdg = 0;
		//
		// if (heading <= 0) {
		// return 0;
		// } else if (heading >= 0 && heading < 45) {
		// newhdg = intDirection;
		// } else if (heading >= 45 && heading < 90) {
		// newhdg = intDirection - 1;
		// } else if (heading >= 90 && heading < 135) {
		// newhdg = intDirection - 2;
		// } else if (heading >= 135 && heading < 180) {
		// newhdg = intDirection - 3;
		// } else if (heading >= 180 && heading < 225) {
		// newhdg = intDirection - 4;
		// } else if (heading >= 225 && heading < 270) {
		// newhdg = intDirection - 5;
		// } else if (heading >= 270 && heading < 315) {
		// newhdg = intDirection - 6;
		// } else if (heading >= 315 && heading < 360) {
		// newhdg = intDirection - 7;
		// }
		//
		// return newhdg;
	}

	/**
	 * Get the handler object;
	 * 
	 * @return
	 */
	public Handler getHandler() {
		return messageHandler;
	}

	/**
	 * The handler of message.
	 */
	@SuppressLint("HandlerLeak")
	private void initHandler() {

		messageHandler = new Handler() {
			public void handleMessage(Message msg) {

				try {
					processedMessage(msg);
				} catch (Exception e) {
					e.printStackTrace();
					Toast.makeText(IMDroid.getContext(), e.getMessage(),
							Toast.LENGTH_SHORT).show();
				}
			}
		};

	}

	/**
	 * Get the current location
	 * 
	 * @return the currentLocation
	 */
	public BDLocation getCurrentLocation() {
		return currentLocation;
	}

	/**
	 * Get the Geo String of the current location.
	 * 
	 * @return the Geo String of the current location.
	 */
	public String getCurrentGeoString() {
		return (currentLocation != null) ? Math.round((currentLocation
				.getLatitude() * 1000))
				+ "--"
				+ Math.round((currentLocation.getLongitude() * 1000)) : "--";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#isRouteDisplayed()
	 */
	protected boolean isRouteDisplayed() {
		return false;
	}

	/**
	 * Get if the activity is active
	 * 
	 * @return the active
	 */
	public boolean isActive() {
		return active;
	}

	/**
	 * Set if the activity is active
	 * 
	 * @param active
	 *            the active to set
	 */
	public void setActive(boolean active) {
		this.active = active;
	}

	/**
	 * Get if it is in mute mode
	 * 
	 * @return the mute
	 */
	public boolean isMute() {
		// return mute;
		return UDPSpeaker.isMute();
	}

	/**
	 * Set if it is in mute mode
	 * 
	 * @param mute
	 *            the mute to set
	 */
	public void setMute(boolean mute) {
		// this.mute = mute;
		UDPSpeaker.setMute(mute);
	}

	/**
	 * The event clicking the button zoomin
	 * 
	 * @param view
	 *            the button of zoom in
	 */
	public void zoomIn(View view) {
		if (!mapController.zoomIn())
			Toast.makeText(this, this.getString(R.string.team_map_zoom_in_max),
					Toast.LENGTH_SHORT).show();

	}

	/**
	 * The event clicking the button zoom out
	 * 
	 * @param view
	 *            the button of zoom out
	 */
	public void zoomOut(View view) {
		if (!mapController.zoomOut())
			Toast.makeText(this,
					this.getString(R.string.team_map_zoom_out_max),
					Toast.LENGTH_SHORT).show();
	}

	/**
	 * The event clicking the button zoom out
	 * 
	 * @param view
	 *            the buttobn of location
	 */
	public void locateMe(View view) {
		try {
			/*
			 * mLocClient.registerLocationListener(myListener);
			 * LocationClientOption option = new LocationClientOption();
			 * option.setOpenGps(true);// 打开gps option.setCoorType("bd09ll"); //
			 * 设置坐标类型 option.setScanSpan(5000); mLocClient.setLocOption(option);
			 * mLocClient.start();
			 */
			ImageButton button = (ImageButton) view;

			// locate me
			teamLeaderOverlay.enableCompass();
			if (teamLeaderOverlay.getMyLocation() != null) {
				GeoPoint temp = new GeoPoint(
						(int) (teamLeaderOverlay.getMyLocation().latitude * 1000000),
						(int) (teamLeaderOverlay.getMyLocation().longitude * 1000000));
				mapController.setCenter(temp);
			}
			// 切换图片
			button.setBackgroundResource(R.drawable.self_centered_on);
			// 重置状态
			isNavigation = !isNavigation;
			bupdateMe = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Mute the sound
	 * 
	 * @param view
	 *            the button of mute
	 */
	public void mute(View view) {
		ImageButton button = (ImageButton) view;
		button.setBackgroundResource(UDPSpeaker.isMute() ? R.drawable.mute_off
				: R.drawable.mute_on);
		setMute(!UDPSpeaker.isMute());
	}

	/**
	 * Set the destination
	 * 
	 * @param view
	 *            the button of setting destination
	 */
	public void setDestination(View view) {
		final EditText destination = new EditText(this);
		destination.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);

		AlertDialog.Builder buidler = new AlertDialog.Builder(
				TeamMapActivity.this);
		buidler.setTitle(R.string.team_map_destination_name);
		buidler.setIcon(android.R.drawable.ic_dialog_info);
		buidler.setView(destination);

		// 按钮 - 是，查找地址
		buidler.setPositiveButton(
				TeamMapActivity.this.getString(R.string.team_btn_search),
				new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {
						if (destination.getText().toString() != null
								&& destination.getText().toString().length() > 0)
							mKSearch.suggestionSearch(destination.getText()
									.toString(), currentCity);
						else
							Toast.makeText(
									TeamMapActivity.this,
									TeamMapActivity.this
											.getString(R.string.team_map_destination_name_empty),
									Toast.LENGTH_SHORT).show();
					}
				});
		// 按钮 - 否
		buidler.setNegativeButton(
				TeamMapActivity.this.getString(R.string.team_btn_cancel),
				new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {
					}
				});

		buidler.show();
	}

	private OnTouchListener callOnTouchListener = new OnTouchListener() {
		/*
		 * (non-Javadoc)
		 * 
		 * @see android.view.View.OnTouchListener#onTouch(android.view.View,
		 * android.view.MotionEvent)
		 */
		public boolean onTouch(View v, MotionEvent event) {
			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				// 按键按下震动
				((Vibrator) IMDroid.getContext().getSystemService(
						Context.VIBRATOR_SERVICE)).vibrate(200);
				// 并发送一次地址
				messageHandler.sendEmptyMessage(EVENT_TEAM_SEND_LOCATION);
				// 显示成员列表
				messageHandler.sendEmptyMessage(EVENT_TEAM_SHOW_MEMBERS);
			}
			if (Team.getCurrentTeam() != null) {
				// 对讲,开始录音
				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					callView.setVisibility(View.VISIBLE);
					
					if (!TeamCallHelper.isRecording
							&& !TeamCallHelper.isStopping)
						TeamCallHelper.startRecording();
				}
				// 对讲,结束录音
				if (event.getAction() == MotionEvent.ACTION_UP) {
					callView.setVisibility(View.GONE);
					// 结束录音
					if (TeamCallHelper.isRecording
							&& !TeamCallHelper.isStopping)
						TeamCallHelper.stopRecording();
				}
			}
			return false;
		}
	};

	/**
	 * The gesture listener
	 */
	private class MapGestureListener extends SimpleOnGestureListener {
		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * android.view.GestureDetector.SimpleOnGestureListener#onLongPress(
		 * android.view.MotionEvent)
		 */
		public void onLongPress(MotionEvent e) {
			// 只有队长可以发送地址
			if (Team.getCurrentTeam() == null
					|| Team.getCurrentTeam().getTeamId() != IMDroid.getUser()
							.getUser_id())
				return;
			final GeoPoint myGeoPoint = mapView.getProjection().fromPixels(
					(int) e.getX(), (int) e.getY());
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(
					TeamMapActivity.this);
			buidler.setMessage(R.string.team_map_confirm_dest);
			// 按钮 - 是，并重新规划路线
			buidler.setPositiveButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_yy),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							// 设置目的地
							Message msg = new Message();
							msg.what = EVENT_TEAM_SEND_DEST_WITH_ROUTE;
							msg.obj = myGeoPoint;
							// 发送目的地给其他队友
							messageHandler.sendMessage(msg);
						}
					});
			// 按钮 - 是，但是不规划路线
			buidler.setNeutralButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_yr),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							// 设置目的地
							Message msg = new Message();
							msg.what = EVENT_TEAM_SEND_DEST_NO_ROUTE;
							msg.obj = myGeoPoint;
							// 发送目的地给其他队友
							messageHandler.sendMessage(msg);
						}
					});
			// 按钮 - 否
			buidler.setNegativeButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_n),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							arg0.dismiss();
						}
					});

			buidler.show();
		}

		public boolean onDown(MotionEvent e) {
			bupdateMe = false;
			ImageButton button = (ImageButton) findViewById(R.id.team_map_location);
			button.setBackgroundResource(R.drawable.self_centered_off);
			return false;
		}
	}

	/**
	 * The seach listener of the map
	 */
	private MKSearchListener mapSearchListener = new MKSearchListener() {
		/**
		 * The name of the destination;
		 */
		private String destinationAddress;
		/**
		 * If need the search the route.
		 */
		private boolean searchRoute;

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetAddrResult(com.baidu.mapapi
		 * .MKAddrInfo, int)
		 */
		public void onGetAddrResult(MKAddrInfo result, int error) {
			if (error != 0) {
				Toast.makeText(TeamMapActivity.this, "Error Code:" + error,
						Toast.LENGTH_LONG).show();
				return;
			}
			Log.d(TAG, "Lat:" + result.geoPt.getLatitudeE6() / 1e6 + "Lon:"
					+ result.geoPt.getLongitudeE6() / 1e6);
			// 设置目的地
			Message msg = new Message();

			msg.what = searchRoute ? EVENT_TEAM_SEND_DEST_WITH_ROUTE
					: EVENT_TEAM_SEND_DEST_NO_ROUTE;
			msg.obj = result.geoPt;
			// 发送目的地给其他队友
			messageHandler.sendMessage(msg);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetBusDetailResult(com.baidu.
		 * mapapi.MKBusLineResult, int)
		 */
		public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetDrivingRouteResult(com.baidu
		 * .mapapi.MKDrivingRouteResult, int)
		 */
		public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) {
			if (arg0 == null) {
				return;
			}
			if (routeOverlay != null)
				mapView.getOverlays().remove(routeOverlay);
			routeOverlay = new RouteOverlay(TeamMapActivity.this, mapView);
			// 只选择第一种
			routeOverlay.setData(arg0.getPlan(0).getRoute(0));
			mapView.getOverlays().add(routeOverlay);
			mapView.invalidate();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetPoiResult(com.baidu.mapapi
		 * .MKPoiResult, int, int)
		 */
		public void onGetPoiResult(MKPoiResult arg0, int arg1, int arg2) {

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetSuggestionResult(com.baidu
		 * .mapapi.MKSuggestionResult, int)
		 */
		public void onGetSuggestionResult(MKSuggestionResult result, int iError) {
			// 如果没有找到目的地
			if (iError != 0 || result == null || result.getSuggestionNum() <= 0) {
				Toast.makeText(
						TeamMapActivity.this,
						TeamMapActivity.this
								.getString(R.string.team_map_destination_error),
						Toast.LENGTH_LONG).show();
				return;
			}
			// 把目的地组成数组，准备显示选择
			int nSize = result.getSuggestionNum();
			final String[] mStrSuggestions = new String[nSize];
			for (int i = 0; i < nSize; i++)
				mStrSuggestions[i] = result.getSuggestion(i).city + "-"
						+ result.getSuggestion(i).key;
			destinationAddress = null;
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(
					TeamMapActivity.this);
			buidler.setTitle(R.string.team_map_destination_name);
			buidler.setIcon(android.R.drawable.ic_dialog_info);
			buidler.setSingleChoiceItems(mStrSuggestions, 0,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							// 记下选择的地址
							destinationAddress = mStrSuggestions[which];

						}
					});
			// 按钮 - 是，且规划线路
			buidler.setPositiveButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_yy),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							destinationAddress = (destinationAddress != null) ? destinationAddress
									: mStrSuggestions[0];
							// 将地址再转为坐标
							String city = destinationAddress.substring(0,
									destinationAddress.indexOf("-"));
							String key = destinationAddress.substring(
									destinationAddress.indexOf("-"),
									destinationAddress.length());
							searchRoute = true;
							Log.d(TAG, "select key:" + key + "city:" + city);
							mKSearch.geocode(key, city);
						}
					});
			// 按钮 - 是，但不规划路线
			buidler.setNeutralButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_yr),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							destinationAddress = (destinationAddress != null) ? destinationAddress
									: mStrSuggestions[0];

							// 将地址再转为坐标
							String city = destinationAddress.substring(0,
									destinationAddress.indexOf("-"));
							String key = destinationAddress.substring(
									destinationAddress.indexOf("-"),
									destinationAddress.length());
							searchRoute = false;
							Log.d(TAG, "select key:" + key + "city:" + city);
							mKSearch.geocode(key, city);
						}
					});
			// 按钮 - 否
			buidler.setNegativeButton(TeamMapActivity.this
					.getString(R.string.team_map_confirm_dest_n),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
						}
					});
			buidler.show();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetTransitRouteResult(com.baidu
		 * .mapapi.MKTransitRouteResult, int)
		 */
		public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.baidu.mapapi.MKSearchListener#onGetWalkingRouteResult(com.baidu
		 * .mapapi.MKWalkingRouteResult, int)
		 */
		public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) {

		}

		@Override
		public void onGetPoiDetailSearchResult(int arg0, int arg1) {
		}

	};

	/**
	 * process the message
	 * 
	 * @param msg
	 *            the message the message
	 * 
	 * @throws Exception
	 */
	private void processedMessage(Message msg) throws Exception {
		switch (msg.what) {
		case EVENT_TEAM_EXIT:
			// 退出队伍
			exitTeam();
			break;
		case EVENT_TEAM_REFRESH:
			refreshMembers();
			break;
		case EVENT_TEAM_UPDATE:
			updateMembers();
			break;
		case EVENT_TEAM_SEND_LOCATION:
			updateLocation(currentLocation);
			break;
		case EVENT_TEAM_SHOW_MEMBERS:
			showAllMemberText();
			break;
		case EVENT_TEAM_HIDE_MEMBERS:
			hideAllMemberText();
			break;
		case EVENT_TEAM_SEND_DEST_NO_ROUTE:
			sendTeamDestination((GeoPoint) msg.obj, false);
			break;
		case EVENT_TEAM_SEND_DEST_WITH_ROUTE:
			sendTeamDestination((GeoPoint) msg.obj, true);
			break;
		case EVENT_TEAM_RECEIVE_LOCATION:
			receiveTeamDestination();
			break;
		case EVENT_CHANGE_CALL_ANIM_ICON:
			changeAnimationIcon(((Integer) msg.obj) % 4);
			break;
		}
	}

	/**
	 * refresh the whole team member list from the server.
	 * 
	 * @throws Exception
	 */
	private void refreshMembers() throws Exception {
		System.out.println("ccccc sizs :");
		new Thread() {
			public void run() {
				try {
					System.out.println("ddddd");
					TeamProcess process = (TeamProcess) ProcessFactory
							.getProcess(TeamProcess.class);
					final Team team = Team.getCurrentTeam();
					// 更新队员列表
					process.refreshTeamMember(team);

					messageHandler.post(new Runnable() {
						public void run() {
							// 更新图层
							teamMemberOverlay.updateMembers(team);
							// 更新目的地
							destinationOverlay.refreshDestination();
						}
					});
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();

	}

	/**
	 * update the team member position.
	 * 
	 * @throws Exception
	 */
	private void updateMembers() throws Exception {
		Team team = Team.getCurrentTeam();
		// 更新图层
		teamMemberOverlay.updateMembers(team);
	}

	/**
	 * Exit from the current team.
	 * 
	 * @throws Exception
	 */
	private void exitTeam() throws Exception {
		// 退出队伍
		new Thread() {
			public void run() {
				try {
					TeamProcess process = (TeamProcess) ProcessFactory
							.getProcess(TeamProcess.class);
					process.exitTeam();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();
		// startActivity(new Intent(this, HomeActivity.class));
		// finish();
	}

	/**
	 * Send the location
	 * 
	 * @param location
	 *            the location to send
	 */
	private void updateLocation(BDLocation location) {
		if (location == null)
			return;
		TeamProcess process = (TeamProcess) ProcessFactory
				.getProcess(TeamProcess.class);
		process.sendLocation(location);
	}

	/**
	 * Send the team destination
	 * 
	 * @param geoPoint
	 *            the geopoint of the destination
	 * @param searchRoute
	 *            if caculate the route
	 * @throws Exception
	 */
	private void sendTeamDestination(GeoPoint geoPoint,
			final boolean searchRoute) throws Exception {
		// 设置目的地
		Team team = Team.getCurrentTeam();
		team.setDestinationLon((float) (geoPoint.getLongitudeE6() / 1E6));
		team.setDestinationLat((float) (geoPoint.getLatitudeE6() / 1E6));
		team.setSearchRoute(searchRoute);

		new Thread() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see java.lang.Thread#run()
			 */
			public void run() {

				try {
					TeamProcess process = (TeamProcess) ProcessFactory
							.getProcess(TeamProcess.class);
					process.sendTeamDestination(Team.getCurrentTeam());
					Log.d(TAG, "searchRoute...." + searchRoute);
				} catch (Exception e) {
					e.printStackTrace();
				}

			}
		}.start();

		destinationOverlay.refreshDestination();

		if (searchRoute) {
			searchRoute((float) currentLocation.getLatitude(),
					(float) currentLocation.getLongitude(),
					(float) (geoPoint.getLatitudeE6() / 1E6),
					(float) (geoPoint.getLongitudeE6() / 1E6));

			LaunchBDNavi((float) currentLocation.getLatitude(),
					(float) currentLocation.getLongitude(),
					(float) (geoPoint.getLatitudeE6() / 1E6),
					(float) (geoPoint.getLongitudeE6() / 1E6));
		} else
			removeRoute();
	}

	private void LaunchBDNavi(float startlat, float startlon, float endlat,
			float endlon) {
		NaviPara para = new NaviPara();
		para.startPoint = new GeoPoint((int) (startlat * 1E6),
				(int) (startlon * 1E6)); // 起点坐标
		para.startName = "从这里开始";
		para.endPoint = new GeoPoint((int) (endlat * 1E6), (int) (endlon * 1E6)); // 终点坐标
		para.endName = "到这里结束";
		try {
			// 调起百度地图客户端导航功能,参数this为Activity。
			BaiduMapNavigation.openBaiduMapNavi(para, this);
		} catch (BaiduMapAppNotSupportNaviException e) {
			// 在此处理异常
			e.printStackTrace();
		}

	}

	/**
	 * Receiving the team destination
	 * 
	 * @throws Exception
	 */
	private void receiveTeamDestination() throws Exception {
		// 刷新地图
		mapView.invalidate();
		// 设置目的地
		Team team = Team.getCurrentTeam();
		if (team != null && !team.isSearchRoute())
			removeRoute();

		// 屏幕移动至目的地
		if (!(team.getDestinationLat() == 0 && team.getDestinationLat() == 0)) {
			destinationOverlay.refreshDestination();
			mapController.setCenter(new GeoPoint((int) (team
					.getDestinationLat() * 1E6), (int) (team
					.getDestinationLon() * 1E6)));
		}
		// 启动导航

		if (team != null && team.isSearchRoute())
			if (!(team.getDestinationLat() == 0 && team.getDestinationLat() == 0)) {
				searchRoute((float) currentLocation.getLatitude(),
						(float) currentLocation.getLongitude(),
						team.getDestinationLat(), team.getDestinationLon());
				LaunchBDNavi((float) currentLocation.getLatitude(),
						(float) currentLocation.getLongitude(),
						team.getDestinationLat(), team.getDestinationLon());
			}

	}

	private void changeAnimationIcon(int index) {
		ImageView left = (ImageView) findViewById(R.id.recording_animate_left);
		ImageView right = (ImageView) findViewById(R.id.recording_animate_right);
		left.setImageResource(anim_icons_left[index]);
		right.setImageResource(anim_icons_right[index]);
	}

	public static void startRecordingAnimation() {
		if (instance != null && instance.animTask != null) {
			instance.animTask.cancel();
			instance.animTask = null;
		}
		if (instance != null) {
			instance.animTask = new TimerTask() {
				long start = System.currentTimeMillis();

				public void run() {
					long passed = System.currentTimeMillis() - start;
					int pos = (int) (passed / 500);
					if (instance != null && instance.getHandler() != null) {
						instance.getHandler()
								.obtainMessage(EVENT_CHANGE_CALL_ANIM_ICON, pos)
								.sendToTarget();
					}
				}
			};
			instance.animTimer.schedule(instance.animTask, 500, 500);
		}

	}

	public static void stopRecordingAnimation() {
		if (instance != null && instance.animTask != null) {
			instance.animTask.cancel();
			instance.animTask = null;
		}
		try {
			Thread.sleep(5);
		} catch (Exception e) {
		}
		if (instance != null) {
			instance.getHandler().obtainMessage(EVENT_CHANGE_CALL_ANIM_ICON, 0)
					.sendToTarget();
		}
	}

	/**
	 * Show member list
	 */
	private void showAllMemberText() {
		final ScrollView scrollView = (ScrollView) findViewById(R.id.team_map_member_sv);
		TextView textView = (TextView) findViewById(R.id.team_map_member_tv);
		// 重置文本
		textView.setText(Html.fromHtml(Team.getCurrentTeam().getAllMemberText(
				currentLocation)));
		// 成员列表的显示、关闭
		scrollView.setVisibility(View.VISIBLE);
		// 成员列表显示5秒
		Timer hideTimer = new Timer();
		hideTimer.schedule(new TimerTask() {
			public void run() {
				messageHandler.sendEmptyMessage(EVENT_TEAM_HIDE_MEMBERS);
			}
		}, 5000);
	}

	/**
	 * Hide the member Text
	 */
	private void hideAllMemberText() {
		final ScrollView scrollView = (ScrollView) findViewById(R.id.team_map_member_sv);
		// 成员列表的显示、关闭
		scrollView.setVisibility(View.GONE);
	}

	/**
	 * Search the route
	 * 
	 * @param startlat
	 *            the start lat
	 * @param startlon
	 *            the start lon
	 * @param endlat
	 *            the end lat
	 * @param endlon
	 *            the end lon
	 */
	private void searchRoute(float startlat, float startlon, float endlat,
			float endlon) {
		Log.d(TAG, "start lat:" + startlat + "start lon:" + startlon);
		Log.d(TAG, "end lat:" + endlat + "end lon:" + endlon);
		// 设置起点
		MKPlanNode start = new MKPlanNode();
		start.pt = new GeoPoint((int) (startlat * 1E6), (int) (startlon * 1E6));
		// 设置终点
		MKPlanNode end = new MKPlanNode();
		end.pt = new GeoPoint((int) (endlat * 1E6), (int) (endlon * 1E6));
		// 计算路线
		mKSearch.setDrivingPolicy(MKSearch.ECAR_TIME_FIRST);
		mKSearch.drivingSearch(null, start, null, end);
	}

	/**
	 * Remove the route
	 * 
	 */
	private void removeRoute() {
		if (routeOverlay != null)
			mapView.getOverlays().remove(routeOverlay);
		mapView.invalidate();
	}

	/**
	 * The text timer
	 */
	private volatile Timer hideTimer = null;

	/**
	 * Show or Hide the specific member
	 * 
	 * @param userId
	 *            the user id
	 */
	public void showMember(final int userId) {
		messageHandler.post(new Runnable() {
			public void run() {
				if (hideTimer != null) {
					hideTimer.cancel();
					hideTimer = null;
				}
				hideTimer = new Timer();
				hideTimer.schedule(new TimerTask() {
					public void run() {
						hideMember();
					}
				}, 10000);
				ScrollView scrollView = (ScrollView) findViewById(R.id.team_map_member_sv_float);
				TextView textView = (TextView) findViewById(R.id.team_map_member_tv_float);
				textView.setText(Team.getCurrentTeam().getMemberText(
						currentLocation, userId));
				scrollView.setVisibility(View.VISIBLE);

				Animation ani = new TranslateAnimation(310f, -400f, 0.0f, 0.0f);
				ani.setDuration(10000);
				ani.setRepeatCount(500);
				ani.setRepeatMode(1);
				textView.startAnimation(ani);
			}
		});
	}

	/**
	 * Hide the member list
	 */
	private void hideMember() {
		messageHandler.post(new Runnable() {
			public void run() {
				hideTimer.cancel();
				hideTimer = null;

				// 恢复原来的队名
				ScrollView scrollView = (ScrollView) findViewById(R.id.team_map_member_sv_float);
				TextView textView = (TextView) findViewById(R.id.team_map_member_tv_float);
				if (Team.getCurrentTeam().getTeamName() != ""
						&& !Team.getCurrentTeam().getTeamName().equals("")) {
					textView.setText(Team.getCurrentTeam().getTeamName());
				}
				textView.setAnimation(null);
				scrollView.setVisibility(View.VISIBLE);
			}
		});

	}

	/**
	 * 检查音量是否调到最大
	 */
	private void checkAudio() {
		audioManager = (AudioManager) this
				.getSystemService(Context.AUDIO_SERVICE);
		int currentVolumn = audioManager
				.getStreamVolume(AudioManager.STREAM_MUSIC);
		int maxVolumn = audioManager
				.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

		Log.d(TAG, "currentVolumn--" + currentVolumn);
		Log.d(TAG, "maxVolumn--" + maxVolumn);

		if (currentVolumn < maxVolumn / 2) {
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(
					TeamMapActivity.this);
			buidler.setIcon(android.R.drawable.ic_dialog_info);
			buidler.setMessage(R.string.team_check_sound);
			// 按钮 - 是，去到媒体音量设置
			buidler.setPositiveButton(
					TeamMapActivity.this.getString(R.string.team_confirm),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							Intent intent = new Intent(
									android.provider.Settings.ACTION_SOUND_SETTINGS);
							TeamMapActivity.this.startActivity(intent);
						}
					});
			// 按钮 - 否
			buidler.setNegativeButton(
					TeamMapActivity.this.getString(R.string.team_cancel),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							arg0.dismiss();
						}
					});

			buidler.create().show();
		}
	}

	/**
	 * 检查GPS是否开启
	 */
	private void checkGPS() {
		LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		boolean gpsOpen = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
		if (!gpsOpen) {
			// 弹出对话框
			AlertDialog.Builder buidler = new AlertDialog.Builder(
					TeamMapActivity.this);
			buidler.setIcon(android.R.drawable.ic_dialog_info);
			buidler.setMessage(R.string.team_check_gps);
			// 按钮 - 是，去到GPS设置
			buidler.setPositiveButton(
					TeamMapActivity.this.getString(R.string.team_confirm),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							Intent intent = new Intent(
									android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
							TeamMapActivity.this.startActivity(intent);
						}
					});
			// 按钮 - 否
			buidler.setNegativeButton(
					TeamMapActivity.this.getString(R.string.team_cancel),
					new OnClickListener() {
						public void onClick(DialogInterface arg0, int arg1) {
							arg0.dismiss();
						}
					});
			buidler.create().show();
		}
	}

	/**
	 * 监听函数，又新位置的时候，格式化成字符串，输出到屏幕中
	 */
	public class MyLocationListenner implements BDLocationListener {

		/**
		 * The last time sending to server.
		 */
		private long lastUpdateTime;
		/**
		 * The last time sending to server.
		 */
		private BDLocation lastUpdateLocation;
		/**
		 * The minimum duration send the location to server.
		 */
		private static final float MIN_SEND_DURATION = 60 * 1000;
		/**
		 * 
		 * The minimum duration send the location to server.
		 */
		private static final float MIN_SEND_DISTANCE = 25;

		@Override
		public void onReceiveLocation(BDLocation location) {
			if (location == null)
				return;

			locData.latitude = location.getLatitude();
			locData.longitude = location.getLongitude();
			locData.accuracy = location.getRadius();
			locData.direction = location.getDerect();

			teamLeaderOverlay.setData(locData);
			mapView.refresh();

			int headingIndex = getHeadingIndex(location.getDerect());

			if (Team.getCurrentTeam() != null) {
				if (IMDroid.getUser().getUser_id() == Team.getCurrentTeam()
						.getTeamId()) {
					teamLeaderOverlay
							.setMarker(TeamMapActivity.this.getResources()
									.getDrawable(arrow_Me[headingIndex]));
				} else {
					teamLeaderOverlay.setMarker(TeamMapActivity.this
							.getResources().getDrawable(
									arrow_Me_Member[headingIndex]));
				}
			}
			if (bupdateMe) {
				mapController.animateTo(new GeoPoint(
						(int) (locData.latitude * 1e6),
						(int) (locData.longitude * 1e6)));
				// myLocation changed so update Members
				try {
					updateMembers();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			onLocationChanged(location);

		}

		public void onLocationChanged(BDLocation location) {

			// 更新最新位置
			currentLocation = location;
			currentCity = (location != null) ? location.getCity() : null;
			IMDroid.setCurrentLocation(location);

			long duration = System.currentTimeMillis() - lastUpdateTime;

			float distance = 0.0f;

			if (lastUpdateLocation != null) {
				Location currLocation = new Location("");
				currLocation.setLatitude(location.getLatitude());
				currLocation.setLongitude(location.getLongitude());

				Location lastLocation = new Location("");
				lastLocation.setLatitude(lastUpdateLocation.getLatitude());
				lastLocation.setLongitude(lastUpdateLocation.getLongitude());

				distance = currLocation.distanceTo(lastLocation);

			} else {
				distance = MIN_SEND_DISTANCE + 1;
			}

			// Log.d(TAG, "duration:" + (duration / 1000) + "  distance:"
			// + distance);
			if (duration > MIN_SEND_DURATION || distance > MIN_SEND_DISTANCE) {
				lastUpdateTime = System.currentTimeMillis();
				lastUpdateLocation = location;
//				Toast.makeText(
//						TeamMapActivity.this,
//						"Location: Lat-" + location.getLatitude() + " Lon-"
//								+ location.getLongitude() + " Dir-"
//								+ location.getDerect(), Toast.LENGTH_SHORT)
//						.show();
				updateLocation(location);
			}
		}

		public void onReceivePoi(BDLocation poiLocation) {
			if (poiLocation == null) {
				return;
			}
		}
	}

	public class NotifyLister extends BDNotifyListener {
		public void onNotify(BDLocation mlocation, float distance) {
		}
	}

	/**
	 * The overlay of team member
	 * 
	 */
	private class TeamMemberOverlay extends ItemizedOverlay<OverlayItem> {
		public TeamMemberOverlay(Drawable marker, MapView arg1) {
			super(marker, arg1);
		}

		/**
		 * The paint
		 */
		/**
		 * The items
		 */
		// private List<OverlayItem> items = new ArrayList<OverlayItem>();
		/**
		 * The marker
		 */
		private int intDrawable = 0;

		private static final float MIN_UPDATE_DURATION = 3 * 60 * 1000;

		/**
		 * Update the team members
		 * 
		 * @param members
		 *            update the members
		 */
		public void updateMembers(Team team) {
			Projection projection = mapView.getProjection();
			// items.clear();
			txtOverlay.removeAll();
			this.removeAll();
			lineOverlay.removeAll();
			GeoPoint myPoint = new GeoPoint(0, 0);

			if (team == null || team.getMembers() == null)
				return;

			if (teamLeaderOverlay.getMyLocation() != null) {
				int lat = (int) (teamLeaderOverlay.getMyLocation().latitude * 1e6);
				int lon = (int) (teamLeaderOverlay.getMyLocation().longitude * 1e6);
				myPoint.setLatitudeE6(lat);
				myPoint.setLongitudeE6(lon);
			}

			for (TeamMember member : team.getMembers().values()) {
				if (member.getLat() == 0 && member.getLon() == 0)
					continue;
				// 如果是自己，则忽略
				if (member.getId() == IMDroid.getUser().getUser_id())
					continue;

				GeoPoint p = new GeoPoint((int) (member.getLat() * 1e6),
						(int) (member.getLon() * 1e6));
				OverlayItem item = new OverlayItem(p, member.getId() + "",
						member.getDisplayName());

				TextItem txtItem = new TextItem();

				Point pointMember = new Point();
				projection.toPixels(p, pointMember);

				pointMember.y = pointMember.y - arrowHeight / 2;

				// txtItem.pt = projection
				// .fromPixels(pointMember.x, pointMember.y);
				txtItem.text = member.getDisplayName();
				txtItem.pt = p;
				txtItem.align = 2;
				Symbol textSymbol1 = new Symbol();
				Symbol.Color textColor1 = textSymbol1.new Color();
				textColor1.alpha = 150;
				textColor1.red = 0;
				textColor1.blue = 255;
				textColor1.green = 0;

				txtItem.fontColor = textColor1;
				txtItem.fontSize = 25;

				txtOverlay.addText(txtItem);

				// make line
				if (myPoint.getLatitudeE6() != 0) {
					Graphic lineGraphic = getGraphic(myPoint, p);
					lineOverlay.setData(lineGraphic);
				}

				int headingIndex = getHeadingIndex(member.getDirect());
				// for team leader
				if (member.getDeviceType() != null) {
					if (member.getId() == team.getTeamId()) {
						if (member.getDeviceType().equals("1")) {
							intDrawable = arrow_Leader[headingIndex];
						} else {
							intDrawable = arrow_Leader_Lite[headingIndex];
						}
					} else {// for team member
						if (member.getDeviceType().equals("1")) {
							intDrawable = arrow_Member[headingIndex];
						} else {
							intDrawable = arrow_Member_Lite[headingIndex];
						}
					}
				} else {
					intDrawable = arrow_Member[headingIndex];
//					Toast.makeText(TeamMapActivity.this,
//							"getDeviceType is null!", Toast.LENGTH_LONG).show();
				}

				// marker = arrow_Member[headingIndex];

				// Toast.makeText(
				// TeamMapActivity.this,
				// "receive ,Derect:" + member.getDirect()
				// + ";headingIndex:" + headingIndex,
				// Toast.LENGTH_LONG).show();

				long inter = System.currentTimeMillis()
						- member.getUpdatedTime();
				Drawable dw = null;
				if (inter > MIN_UPDATE_DURATION) {
					if (member.getDeviceType().equals("1")) {
						dw = getDrawableFromBitmap(-1, member.getDisplayName());

					} else {
						dw = getDrawableFromBitmap(-2, member.getDisplayName());
					}
				} else {
					dw = getDrawableFromBitmap(intDrawable,
							member.getDisplayName());
				}
				item.setMarker(dw);
				member.setUpdatedTime(System.currentTimeMillis());
				boundCenter(item);

				this.addItem(item);
			}
			mapView.refresh();
		}

		private Drawable getDrawableFromBitmap(int headingIndex, String strSrc) {
			Bitmap photo = null;
			switch (headingIndex) {
			case -1:
				photo = BitmapFactory.decodeResource(getResources(),
						R.drawable.arrow_gray);
				break;
			case -2:
				photo = BitmapFactory.decodeResource(getResources(),
						R.drawable.arrow_lite_gray);
				break;
			default:
				photo = BitmapFactory.decodeResource(getResources(),
						headingIndex);
			}

			Paint p = new Paint();
			int width = photo.getWidth() + (int) p.measureText(strSrc), hight = photo
					.getHeight();
			System.out.println("宽" + width + "高" + hight);

			Bitmap icon = Bitmap.createBitmap(width, hight + 40,
					Bitmap.Config.ARGB_8888);
			Canvas canvas = new Canvas(icon);

			Paint photoPaint = new Paint();
			photoPaint.setDither(true);
			photoPaint.setFilterBitmap(true);

			Rect src = new Rect(0, 0, photo.getWidth(), photo.getHeight());
			int intLeft = (int) ((width - photo.getWidth()) / 2);
			int intRight = (int) ((width + photo.getWidth()) / 2);
			Rect dst = new Rect(intLeft, 50, intRight, hight + 50);
			canvas.drawBitmap(photo, src, dst, photoPaint);

			Paint textPaint = new Paint(Paint.FAKE_BOLD_TEXT_FLAG
					| Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
			textPaint.setTextSize(20.0f);
			textPaint.setTypeface(Typeface.DEFAULT_BOLD);
			textPaint.setColor(Color.RED);

			canvas.drawText(strSrc, 0, 60, textPaint);
			canvas.save(Canvas.ALL_SAVE_FLAG);
			canvas.restore();

			BitmapDrawable bd = new BitmapDrawable(getResources(), icon);
			bd.setBounds(-150, -150, 15, 15);
			// return getResources().getDrawable(R.drawable.arrow_leader_180);
			return bd;
		}

		private Graphic getGraphic(GeoPoint pt1, GeoPoint pt2) {
			Geometry lineGeometry = new Geometry();
			GeoPoint[] linePoints = new GeoPoint[2];
			linePoints[0] = pt1;
			linePoints[1] = pt2;
			lineGeometry.setPolyLine(linePoints);

			Symbol lineSymbol = new Symbol();
			Symbol.Color lineColor = lineSymbol.new Color();
			lineColor.red = 10;
			lineColor.green = 10;
			lineColor.blue = 255;
			lineColor.alpha = 255;
			lineSymbol.setLineSymbol(lineColor, 3);

			Graphic lineGraphic = new Graphic(lineGeometry, lineSymbol);
			return lineGraphic;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#createItem(int)
		 */
		// protected OverlayItem createItem(int i) {
		// return items.get(i);
		// }

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#size()
		 */
		// public int size() {
		// return items.size();
		// }
	}

	/**
	 * The overlay of destination
	 * 
	 */
	private class DestinationOverlay extends ItemizedOverlay<OverlayItem> {
		/**
		 * The map view
		 */
		MapView mv;

		/**
		 * The default constructur
		 * 
		 * @param arg0
		 *            the drawable
		 * @param arg1
		 *            the map view
		 */
		public DestinationOverlay(Drawable arg0, MapView arg1) {
			super(arg0, arg1);
			mv = arg1;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.map.ItemizedOverlay#onTap(int)
		 */
		protected boolean onTap(int index) {
			Team team = Team.getCurrentTeam();
			if (team != null
					&& !(team.getDestinationLat() == 0 && team
							.getDestinationLat() == 0)) {
				LaunchBDNavi((float) currentLocation.getLatitude(),
						(float) currentLocation.getLongitude(),
						team.getDestinationLat(), team.getDestinationLon());
			}
			return true;
		}

		/**
		 * Refresh the destination
		 */
		public void refreshDestination() {
			this.removeAll();
			Team team = Team.getCurrentTeam();
			if (team != null
					&& !(team.getDestinationLat() == 0 && team
							.getDestinationLat() == 0)) {
				GeoPoint geoPoint = new GeoPoint(
						(int) (team.getDestinationLat() * 1E6),
						(int) (team.getDestinationLon() * 1E6));
				OverlayItem item = new OverlayItem(geoPoint, "", "");
				this.addItem(item);
			}
			mv.refresh();

		}
	}

	/**
	 * The map view listener
	 */
	private MKMapViewListener mapViewListener = new MKMapViewListener() {

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.MKMapViewListener#onMapMoveFinish()
		 */
		public void onMapMoveFinish() {
			if (isNavigation) {
				// locateMe(findViewById(R.id.team_map_location));
			}
		}

		@Override
		public void onClickMapPoi(MapPoi mapPoiInfo) {
			String title = "";
			if (mapPoiInfo != null) {
				title = mapPoiInfo.strText;

				// Toast.makeText(
				// TeamMapActivity.this,
				// title + ":" + mapPoiInfo.geoPt.getLatitudeE6() + ","
				// + mapPoiInfo.geoPt.getLongitudeE6(),
				// Toast.LENGTH_SHORT).show();

				// 只有队长可以发送地址
				if (Team.getCurrentTeam() == null
						|| Team.getCurrentTeam().getTeamId() != IMDroid
								.getUser().getUser_id())
					return;
				final GeoPoint myGeoPoint = mapPoiInfo.geoPt;
				// 弹出对话框
				AlertDialog.Builder buidler = new AlertDialog.Builder(
						TeamMapActivity.this);
				buidler.setMessage(getResources().getString(
						R.string.team_map_confirm_dest)
						+ "【" + title + "】");
				// 按钮 - 是，并重新规划路线
				buidler.setPositiveButton(TeamMapActivity.this
						.getString(R.string.team_map_confirm_dest_yy),
						new OnClickListener() {
							public void onClick(DialogInterface arg0, int arg1) {
								try {
									sendTeamDestination(myGeoPoint, true);
								} catch (Exception e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
						});
				// 按钮 - 是，但是不规划路线
				buidler.setNeutralButton(TeamMapActivity.this
						.getString(R.string.team_map_confirm_dest_yr),
						new OnClickListener() {
							public void onClick(DialogInterface arg0, int arg1) {
								try {
									sendTeamDestination(myGeoPoint, false);
								} catch (Exception e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
						});
				// 按钮 - 否
				buidler.setNegativeButton(TeamMapActivity.this
						.getString(R.string.team_map_confirm_dest_n),
						new OnClickListener() {
							public void onClick(DialogInterface arg0, int arg1) {
								arg0.dismiss();
							}
						});

				buidler.show();
			}
		}

		@Override
		public void onGetCurrentMap(Bitmap arg0) {
		}

		@Override
		public void onMapAnimationFinish() {
		}

	};

	public static class TeamCallHelper {
		/**
		 * The TAG of the process
		 */
		private final static String TAG = "RecordSoundProcess";
		/**
		 * The tag to indicate if it is recording
		 */
		private static volatile boolean isRecording = false;
		/**
		 * The tag to indicate if it is stopping
		 */
		private static volatile boolean isStopping = false;

		// 监测录音长度的定时器
		private volatile static Timer recordLengthTimer;
		// 监测录音长度的工作
		private volatile static TimerTask recordLengthTask;

		/**
		 * Start Record
		 */
		private static void startRecording() {
			Log.d(TAG, "Start Recording....");
			// 已经在录音或停止中，退出
			if (isRecording || isStopping)
				return;
			
			Team ct = Team.getCurrentTeam();
			boolean shouldRecord = (ct != null && ct.getMembers() != null && ct.getMembers().size() > 1);
			if(!shouldRecord)
				return;

			startRecordingAnimation();

			// 更改状态
			isRecording = true;
			// 准备录音
			/*
			 * recorder = new MediaRecorder();
			 * recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
			 * recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
			 * String geo = (TeamMapActivity.instance != null) ?
			 * TeamMapActivity.instance .getCurrentGeoString() : "--";
			 * 
			 * // 给后缀换个不常用的，以使音乐播放器不自动添加到播放列表 ida = Im-Droid Audio soundFile =
			 * IMDroid.TEMP_FOLDER + IMDroid.getUser().getUser_id() + "_" +
			 * Team.getCurrentTeam().getTeamId() + "_" +
			 * System.currentTimeMillis() + "_" + geo + ".ida";
			 * 
			 * recorder.setOutputFile(soundFile);
			 * recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
			 * Log.d(TAG, "开始录音: " + soundFile); try { recorder.prepare(); }
			 * catch (Exception e) { e.printStackTrace();
			 * PlaySoundProcess.playSound(PlaySoundProcess.wrong); }
			 * recorder.start();
			 */
			UDPMicrophone.startRecording(new StreamListener() {
				public void onStream(ByteBuffer buf) {
					UDPServer.sendAudioPack(buf);
				}
			});
			PlaySoundProcess.playSound(PlaySoundProcess.start);

			// 准备一分钟计数器
			if (recordLengthTimer == null)
				recordLengthTimer = new Timer();
			recordLengthTask = new TimerTask() {
				public void run() {
					recordLengthTask = null;
					stopRecording();
				}
			};
			recordLengthTimer.schedule(recordLengthTask, 30000);
		}

		/**
		 * Stop record
		 */
		public static void stopRecording() {
			Log.d(TAG, "Stop Recording....");
			if (!isRecording || isStopping)
				return;
			// 关闭检测时间过长线程
			if (recordLengthTask != null) {
				recordLengthTask.cancel();
				recordLengthTask = null;
			}

			isStopping = true;
			isRecording = false;

			new Thread() {
				public void run() {
					try {
						Thread.sleep(300);
					} catch (Exception e) {
					}
					try {
						UDPMicrophone.stopRecording();
					} catch (Exception e) {
						e.printStackTrace();
					} finally {
						isRecording = false;
					}
					stopRecordingAnimation();
					PlaySoundProcess.playSound(PlaySoundProcess.end);
					isStopping = false;
				}
			}.start();
			/*
			 * if (recorder == null) { return; }
			 * 
			 * isStopping = true;
			 * 
			 * final MediaRecorder myRecorder = recorder; recorder = null; long
			 * now = (new Date()).getTime(); final boolean shouldSend = (now -
			 * recoderTime > 1000);
			 * 
			 * new Thread() { public void run() { // 等一段时间再停止录音，避免漏语音 try {
			 * Thread.sleep(300); // 停止录音，更新文件 myRecorder.stop();
			 * PlaySoundProcess.playSound(PlaySoundProcess.end);
			 * myRecorder.release(); stopRecordingAnimation(); // 发送并通知用户 if
			 * (shouldSend) { TeamProcess process = (TeamProcess) ProcessFactory
			 * .getProcess(TeamProcess.class);
			 * process.broadcast(soundFile.substring(soundFile .lastIndexOf("/")
			 * + 1)); } } catch (Exception e) {
			 * PlaySoundProcess.playSound(PlaySoundProcess.wrong);
			 * e.printStackTrace(); } finally { isStopping = false; } }
			 * }.start();
			 */
		}
	}
}